#ifndef SELECTORIMPL_H_INCLUDED
#define SELECTORIMPL_H_INCLUDED

#include "ChildSelector.h"
#include <string>
using std::string;

class CharacterDataSelectorImpl : public CharacterDataSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

	const string& getData()const;

public:
	CharacterDataSelectorImpl();
	CharacterDataSelectorImpl(const string& _data);
	virtual ~CharacterDataSelectorImpl();

	inline void setData(const string& _data)
	{
		data = _data;
	}

private:
	string data;
};

class ChildSelectorImpl : public DescendantSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

    virtual const Selector& getAncestorSelector()const;
	virtual const SimpleSelector& getSimpleSelector()const;

public:
	ChildSelectorImpl();
	ChildSelectorImpl(const Selector& parent,
					  const SimpleSelector& child);
	ChildSelectorImpl(const ChildSelectorImpl& aChildSelector);
	virtual ~ChildSelectorImpl();

	ChildSelectorImpl& operator=(const ChildSelectorImpl& aChildSelector);

	inline void setAncestorSelector(const Selector& _ancestorSelector)
	{
		if(ancestorSelector)
		{
			delete ancestorSelector;
			ancestorSelector = NULL;
		}
		ancestorSelector = _ancestorSelector.Copy();
	}

	inline void setSimpleSelector(const SimpleSelector& _simpleSelector)
	{
		if(simpleSelector)
		{
			delete simpleSelector;
			simpleSelector = NULL;
		}
		simpleSelector = dynamic_cast<SimpleSelector*>(_simpleSelector.Copy());
	}

private:
	Selector* ancestorSelector;
	SimpleSelector* simpleSelector;
};

class ConditionalSelectorImpl : public ConditionalSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

    virtual const SimpleSelector& getSimpleSelector()const;
	virtual const Condition& getCondition()const;

public:
	ConditionalSelectorImpl();
	ConditionalSelectorImpl(const SimpleSelector& aSimpleSelector,
							const Condition& aCondition);
	ConditionalSelectorImpl(const ConditionalSelectorImpl& aConditionalSelector);
	virtual ~ConditionalSelectorImpl();

	ConditionalSelectorImpl& operator=(const ConditionalSelectorImpl&
										         aConditionalSelector);

	inline void setSimpleSelector(const SimpleSelector& aSimpleSelector)
	{
		if(m_simpleSelector)
		{
			delete m_simpleSelector;
			m_simpleSelector = NULL;
		}
		m_simpleSelector = dynamic_cast<SimpleSelector*>(aSimpleSelector.Copy());
	}

	inline void setCondition(const Condition& aCondition)
	{
		if(m_condition)
		{
			delete m_condition;
			m_condition = NULL;
		}
		m_condition = aCondition.Copy();
	}

private:
	SimpleSelector* m_simpleSelector;
	Condition* m_condition;
};

class DescendantSelectorImpl : public DescendantSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

	virtual const Selector& getAncestorSelector()const;
	virtual const SimpleSelector& getSimpleSelector()const;

public:
	DescendantSelectorImpl();
	DescendantSelectorImpl(const Selector& parent,
						   const SimpleSelector& child);
	DescendantSelectorImpl(const DescendantSelectorImpl&
							         aDescendantSelector);
	virtual ~DescendantSelectorImpl();

	DescendantSelectorImpl& operator=(const DescendantSelectorImpl&
									          aDescendantSelector);

	inline void setAncestorSelector(const Selector& _ancestorSelector)
	{
		if(ancestorSelector)
		{
			delete ancestorSelector;
			ancestorSelector = NULL;
		}
		ancestorSelector = _ancestorSelector.Copy();
	}

	inline void setSimpleSelector(const SimpleSelector& _simpleSelector)
	{
		if(simpleSelector)
		{
			delete simpleSelector;
			simpleSelector = NULL;
		}
		simpleSelector = dynamic_cast<SimpleSelector*>(_simpleSelector.Copy());
	}

private:
	Selector* ancestorSelector;
	SimpleSelector* simpleSelector;
};

class ElementSelectorImpl : public ElementSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

    virtual const string* getNamespaceURI()const;
	virtual const string* getLocalName()const;

public:
	ElementSelectorImpl();
	ElementSelectorImpl(const string& alocalName);
	virtual ~ElementSelectorImpl();

	inline void setLocalName(const string& alocalName)
	{
		localName = alocalName;
	}

private:
	string localName;
};

class PseudoElementSelectorImpl : public ElementSelector
{
public:
	virtual SelectorType getSelectorType()const;
    virtual Selector* Copy()const;
    virtual const string* toString()const;

    virtual const string* getNamespaceURI()const;
	virtual const string* getLocalName()const;

public:
	PseudoElementSelectorImpl();
	PseudoElementSelectorImpl(const string& alocalName);
	virtual ~PseudoElementSelectorImpl();

	inline void setLocalName(const string& alocalName)
	{
		localName = alocalName;
	}

private:
	string localName;

};

class SelectorFactoryImpl : public SelectorFactory
{
public:
	virtual ConditionalSelector* createConditionalSelector(SimpleSelector* selector,
						  Condition* condition)throw(CSSException);

	virtual SimpleSelector* createAnyNodeSelector()throw(CSSException);

	virtual SimpleSelector* createRootNodeSelector()throw(CSSException);

	virtual NegativeSelector* createNegativeSelector(SimpleSelector* selector)
											 throw(CSSException);

	virtual ElementSelector* createElementSelector(const string* namespaceURI,
										   const string& tagName)
										   throw(CSSException);

	virtual CharacterDataSelector* createTextNodeSelector(const string& data)
										   throw(CSSException);

	virtual CharacterDataSelector* createCDataSectionSelector(const string& data)
										   throw(CSSException);

	virtual ProcessingInstructionSelector*
	createProcessingInstructionSelector(const string& target,
										const string& data)
										throw(CSSException);

	virtual CharacterDataSelector* createCommentSelector(const string& data)
										throw(CSSException);

	virtual ElementSelector* createPseudoElementSelector(const string* namespaceURI,
										const string& pseudoName)
										throw(CSSException);

	virtual DescendantSelector* createDescendantSelector(Selector* parent,
												 SimpleSelector* descendant)
												 throw(CSSException);

	virtual DescendantSelector* createChildSelector(Selector* parent,
											SimpleSelector* child)
											throw(CSSException);

	virtual SiblingSelector* createDirectAdjacentSelector(short nodeType,
												  Selector* child,
												  SimpleSelector* directAdjacent)
											throw(CSSException);
};


#endif // SELECTORIMPL_H_INCLUDED
